package com.itfenghuang.day13;

public class A06_端口和协议 {
    public static void main(String[] args) {
        /**
         *  端口: 设备上的应用程序的唯一标识,每一个端口都有各自的端口号
         *  端口号两个字节表示  范围: 0--65535 其中1到1023已经被知名软件占用
         *      重启tomcat 端口号被占用 , 1,将这个端口的程序杀死 2, 重启电脑
         *
         *  协议:
         *      UDP协议: 用户数据协议 ( User Datagram protocol)
         *      无连接通信协议,在通信时,发送端和接收端不建立逻辑连接,不安全
         *
         *      TCP协议:  传输控制协议(Transmission Control Protocol )
         *      面向连接的通信协议,在传输数据之前,客户端和服务端建立逻辑连接,然后再进行
         *      传输数据
         *      在TCP连接中必须明确客户端和服务端,由客户端向服务端发出连接请求,每次创建连接
         *      需要经过"三次握手" ,以及每次断开连接需要经过"四次挥手"
         *
         *      三次握手: TCP协议中,在发送数据的准备阶段,客户端和服务端之间会进行三次交互
         *                用来保证连接的可靠性
         *
         *
         *
         */

//        【问题1】为什么连接的时候是三次握手，关闭的时候却是四次握手？

//        答：因为当Server端收到Client端的SYN连接请求报文后，可以直接发送SYN+ACK报文。
//        其中ACK报文是用来应答的，SYN报文是用来同步的。但是关闭连接时，当Server端收到FIN报文时，
//        很可能并不会立即关闭SOCKET，所以只能先回复一个ACK报文，告诉Client端，"你发的FIN报文我收到了"。
//        只有等到我Server端所有的报文都发送完了，我才能发送FIN报文，因此不能一起发送。故需要四步握手。

//        【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态？

//        答：虽然按道理，四个报文都发送完毕，我们可以直接进入CLOSE状态了，
//        但是我们必须假象网络是不可靠的，有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。
//        在Client发送出最后的ACK回复，但该ACK可能丢失。Server如果没有收到ACK，将不断重复发送FIN片段。
//        所以Client不能立即关闭，它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。
//        Client会设置一个计时器，等待2MSL的时间。如果在该时间内再次收到FIN，那么Client会重发ACK并再次等待2MSL。
//        所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间，
//        2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL，Client都没有再次收到FIN，那么Client推断ACK已经被成功接收，则结束TCP连接。

//        【问题3】为什么不能用两次握手进行连接？

//        答：3次握手完成两个重要的功能，既要双方做好发送数据的准备工作(双方都知道彼此已准备好)，
//        也要允许双方就初始序列号进行协商，这个序列号在握手过程中被发送和确认。

//        现在把三次握手改成仅需要两次握手，死锁是可能发生的。作为例子，考虑计算机S和C之间的通信，
//        假定C给S发送一个连接请求分组，S收到了这个分组，并发 送了确认应答分组。按照两次握手的协定，
//        S认为连接已经成功地建立了，可以开始发送数据分组。可是，C在S的应答分组在传输中被丢失的情况下，
//        将不知道S 是否已准备好，不知道S建立什么样的序列号，C甚至怀疑S是否收到自己的连接请求分组。
//        在这种情况下，C认为连接还未建立成功，将忽略S发来的任何数据分 组，只等待连接确认应答分组。
//        而S在发出的分组超时后，重复发送同样的分组。这样就形成了死锁。

//        【问题4】如果已经建立了连接，但是客户端突然出现故障了怎么办？

//        TCP还设有一个保活计时器，显然，客户端如果出现故障，服务器不能一直等下去，白白浪费资源。
//        服务器每收到一次客户端的请求后都会重新复位这个计时器，时间通常是设置为2小时，
//        若两小时还没有收到客户端的任何数据，服务器就会发送一个探测报文段，以后每隔75秒钟发送一次。
//        若一连发送10个探测报文仍然没反应，服务器就认为客户端出了故障，接着就关闭连接。



    }
}
